package edu.gatech.teamrocket;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import edu.gatech.teamrocket.TaskArrayAdapter.ViewHolder;
import edu.gatech.teamrocket.models.Auth;
import edu.gatech.teamrocket.models.Category;
import edu.gatech.teamrocket.models.Task;

public class ListActivity extends Activity implements OnClickListener {
	DewApplication app;
	Auth auth;
	
	private List<Task> tasks;
	
	// our three different filter options
	private Category filterCategory;
	private Date filterDate;
	private boolean filterCompleted;
	// booleans to see if we should turn that filter on or off
	private boolean filterByComplete;
	private boolean filterByDate;
	private boolean filterByCategory;
	
	private ListView taskListView;
	private TaskArrayAdapter taskAdapter;
	private Dao<Task, Integer> taskDao;
	private Button addButton;
	private Button filterButton;
	private Button moreButton;
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		app = (DewApplication) getApplicationContext();
		auth = app.getAuth();
		
		setContentView(R.layout.list);
		
		taskListView = (ListView) findViewById(R.id.taskList);
		registerForContextMenu(taskListView);
		
		try {
			taskDao = app.getHelper().getTaskDao();
			updateList();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
		addButton = (Button) findViewById(R.id.addButton);
		filterButton = (Button) findViewById(R.id.filterButton);
		moreButton = (Button) findViewById(R.id.moreButton);
		addButton.setOnClickListener(this);
		filterButton.setOnClickListener(this);
		moreButton.setOnClickListener(this);
	}
	
	/**
	 * Creates context menu for each item.
	 */
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.task_context_menu, menu);
	}
	
	/**
	 * Performs an action when a context item is selected.
	 */
	public boolean onContextItemSelected(MenuItem item) {
	    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
	    switch (item.getItemId()) {
	        case R.id.menu_edit:
	        	Task task = taskAdapter.getItem((int) info.id);
	        	Intent i = new Intent(getApplicationContext(), EditTaskActivity.class);
	        	i.putExtra("TASK_ID", task.getId());
				startActivity(i);
	            return true;
	        case R.id.menu_delete:
				try {
					taskAdapter.deleteItem((int) info.id);
					updateList();
				} catch (SQLException e) {
					throw new RuntimeException();
				}
	            return true;
	        default:
	            return super.onContextItemSelected(item);
	    }
	}
	
	/**
	 * Used to update the list of tasks and reset the adapter on the ListView. Can be called from the FilterDialog's callback after setting the new filter options.
	 * @throws SQLException
	 */
	private void updateList() throws SQLException {
		QueryBuilder<Task, Integer> queryBuilder = taskDao.queryBuilder();
		Where<Task, Integer> where = queryBuilder.where();
		where.eq("user_id", auth.getUser());
		if (filterByCategory) {
			where.and().eq("category_id", filterCategory); // concatenate category filter
		}
		if (filterByDate) {
			System.out.println(filterDate);
			where.and(where, where.or(where.ge("time", filterDate), where.eq("recurring", true))); // concatenate date filter
		}
		if (filterByComplete) {
			where.and().eq("completed", filterCompleted); // concatenate completed filter
		}
		tasks = taskDao.query(queryBuilder.prepare());
		taskAdapter = new TaskArrayAdapter(this, tasks);
		taskListView.setAdapter(taskAdapter);
		taskListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		taskListView.setItemsCanFocus(false);
		taskListView.setEmptyView((TextView) findViewById(R.id.emptyList));
	}
	
	/**
	 * Used to set filter variables.
	 */
	public void setFilter(boolean filterByCategory, boolean filterByDate, boolean filterByComplete, Category filterCategory, Date filterDate, boolean filterCompleted) {
		this.filterByCategory = filterByCategory;
		this.filterByDate = filterByDate;
		this.filterByComplete = filterByComplete;
		this.filterCategory = filterCategory;
		this.filterDate = filterDate;
		this.filterCompleted = filterCompleted;
	}
	
	/**
	 * Creates the menu for allowing users to add items, edit categories, change the filter, and logout.
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.list_menu, menu);
		return true;
    }
	
	/**
	 * Calls the corresponding functionality for the menu button pressed.
	 */
    public boolean onOptionsItemSelected(MenuItem item) {
		Intent i;
    	switch (item.getItemId()) {
	        case R.id.menu_addTask: // Add Task button
	        	// start the activity for creating a new task
	        	i = new Intent(getApplicationContext(), NewTaskActivity.class);
				startActivity(i);
				return true;
				
	        case R.id.menu_deleteSelected: // Delete Selected button
	        	try {
	        		if (taskAdapter.deleteCompleted()) {
	        			updateList();
	    	            Toast.makeText(this, "Deleted!", Toast.LENGTH_SHORT).show();
	        		} else {
	    	            Toast.makeText(this, "Nothing to delete!", Toast.LENGTH_SHORT).show();
	        		}
	        	} catch (Exception e) {
	        		throw new RuntimeException();
	        	}
	            return true;
	 
	        case R.id.menu_editCategories: // Edit Categories button
	        	i = new Intent(this, CategoryListActivity.class);
				startActivity(i);
	            return true;
	 
	        case R.id.menu_filter: // Filter button
	        	/**
	        	 * Custom callback method that allows us to bring filter information from the dialog into the activity.
	        	 */
	            class OnReadyListener implements FilterDialog.ReadyListener {
					@Override
					public void ready(boolean filterByCategoryRes,
							boolean filterByDateRes, boolean filterByCompleteRes,
							Category category, Date date, boolean completed) {
						setFilter(filterByCategoryRes, filterByDateRes, filterByCompleteRes, category, date, completed);
						try {
							updateList();
						} catch (SQLException e) {
							throw new RuntimeException(e);
						}
					}
	            }
	            
	        	// bring up the custom filter dialog, based on filter_dialog.xml
	        	FilterDialog dialog = new FilterDialog(this, new OnReadyListener());
	        	

	        	dialog.show();
	            return true;
	 
	        case R.id.menu_logout: // Logout button
	        	// logout through Auth, clear the history stack
				auth.logout();
				Toast.makeText(this, "You've been logged out!", Toast.LENGTH_LONG).show();
				i = new Intent(getApplicationContext(), LoginActivity.class);
	    		i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // remove this activity from history
	    		startActivity(i);
	    		finish();
	    		return true;
	    		
	        case R.id.menu_map:
				i = new Intent(this, TaskMapActivity.class);
				startActivity(i);
	        	return true;
	            
	        default:
	            return super.onOptionsItemSelected(item);
        }
    }
    
    /**
     * Button Bar listener that calls the menu button actions.
     */
	public void onClick(View item) {
		Intent i;
		switch (item.getId()) {
		case R.id.addButton:
        	i = new Intent(getApplicationContext(), NewTaskActivity.class);
			startActivity(i);
			break;
		case R.id.filterButton:
        	/**
        	 * Custom callback method that allows us to bring filter information from the dialog into the activity.
        	 */
            class OnReadyListener implements FilterDialog.ReadyListener {
				@Override
				public void ready(boolean filterByCategoryRes,
						boolean filterByDateRes, boolean filterByCompleteRes,
						Category category, Date date, boolean completed) {
					setFilter(filterByCategoryRes, filterByDateRes, filterByCompleteRes, category, date, completed);
					try {
						updateList();
					} catch (SQLException e) {
						throw new RuntimeException(e);
					}
				}
            }
            
        	// bring up the custom filter dialog, based on filter_dialog.xml
        	FilterDialog dialog = new FilterDialog(this, new OnReadyListener());
        	dialog.show();
        	break;
		case R.id.moreButton:
			openOptionsMenu();
			break;
		}
	}
}
